﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ProjectBase.Core;

using $prjsn$.Common;
using $prjsn$.Common.Data;
using $prjsn$.Common.Validation;

namespace $safeprojectname$
{
    public class FilterValidatorBase<TEntity, TFilter, TID> : ValidatorBase<TFilter>, IFilterValidator<TFilter, TID>
        where TEntity : class, IPersistentObjectWithTypedId<TID> 
        where TFilter : class, IFilter<TID>
    {
        public bool Validate(TFilter item, IPublishingReporter reporter)
        {
            return Validate(item, ValidateOn.Find, reporter);
        }
        protected override void Init(RuleCollection<TFilter> rules)
        {
            rules.For(filter => filter.SkipRows).RequireValueBetween(0, int.MaxValue).WhenFiltering();
            rules.For(filter => filter.CurrentPage).RequireValueBetween(0, int.MaxValue).WhenFiltering();
            rules.For(filter => filter.TakeRows).RequireValueBetween(1, 999)
                .WhenFiltering()
                .ApplyOnClient();

            rules.Assure(CheckMaxRowsPageLimit)
                .WhenFiltering()
                .ApplyOnServer();

            var selectRule = new SelectExistingPropertiesRule<TFilter, TID, TEntity>(MetaDataProvider);
            rules.Add(selectRule);

            var orderByRule = new OrderByExistingPropertiesRule<TFilter, TID, TEntity>(MetaDataProvider);
            rules.Add(orderByRule);

        }

        protected const int MaxRows = 999;
        protected ValidationResult CheckMaxRowsPageLimit(TFilter filter, out ValidationMessage message)
        {
            message = null;

            if (filter.TakeRows < 1)
            {
                // less than 0
                message = new ValidationMessage(Str.Messages.ValueTooLow4)
                {
                    "TakeRows".GetLocalized(),
                    "Filter",
                    filter.TakeRows,
                    MaxRows,
                };
                return ValidationResult.Error;
            }

            var isRowsLimitCorrect = filter.TakeRows <= MaxRows
                || filter.ExportAllRows;

            // OK
            if (isRowsLimitCorrect)
            {
                return ValidationResult.IsValid;
            }

            // too much rows
            message = new ValidationMessage(Str.Messages.ValueTooHigh4)
            {
                "TakeRows".GetLocalized(),
                "Filter",
                filter.TakeRows ,
                MaxRows,
            };
            return ValidationResult.Error;
        }
        public virtual IMetaDataProvider<TEntity, TID> MetaDataProvider { protected get; set; }
    }
}